﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common.ExpressionParsing;
using Common.Exceptions;
using Tools;
using Common;

namespace Service.BusinessLogic
{
    public class BusinessLogicCommonVisitorExtension : BaseBusinessLogicVisitorExtension
    {
        public BusinessLogicCommonVisitorExtension(Object currentBusinessEntity, DateTime timeStamp)
            : base(currentBusinessEntity, timeStamp)
        { }

        
        [FunctionExtension(FunctionIdentifier = "SubString")]
        public Object SubString()
        {
            if (FunctionParameters.Length != 3)
                throw new BusinessLogicException(
                    ExceptionHelper.excode_generatesscc_function_takes_1_parameter
                    , "'SubString' function takes 3 parameter");

            FunctionParameters[0].Accept(Visitor);
            String src = Visitor.Result.ToString();

            FunctionParameters[1].Accept(Visitor);
            Int32 index = (Int32)Visitor.Result;

            FunctionParameters[2].Accept(Visitor);
            Int32 length = (Int32)Visitor.Result;

            String resultSubString = src.Substring(index, length);
            
            return resultSubString;
        }

        [FunctionExtension(FunctionIdentifier = "AddToDate")]
        public Object AddToDate()
        {
            if (FunctionParameters.Length != 7)
                throw new BusinessLogicException(
                    ExceptionHelper.excode_addtodate_function_takes_6_parameter
                    , "'AddToDate' function takes 6 parameter");

            FunctionParameters[0].Accept(Visitor);
            Int32 years = (Int32)Visitor.Result;

            FunctionParameters[1].Accept(Visitor);
            Int32 months = (Int32)Visitor.Result;

            FunctionParameters[2].Accept(Visitor);
            Int32 days = (Int32)Visitor.Result;

            FunctionParameters[3].Accept(Visitor);
            Int32 hours = (Int32)Visitor.Result;

            FunctionParameters[4].Accept(Visitor);
            Int32 minutes = (Int32)Visitor.Result;

            FunctionParameters[5].Accept(Visitor);
            Int32 seconds = (Int32)Visitor.Result;

            FunctionParameters[6].Accept(Visitor);
            Int32 miliSeconds = (Int32)Visitor.Result;

            DateTime resultAddToDate = TimeStamp.AddYears(years).AddMonths(months).AddDays(days)
                .AddHours(hours).AddMinutes(minutes).AddSeconds(seconds).AddMilliseconds(miliSeconds);

            return resultAddToDate;
        }
                
        [FunctionExtension(FunctionIdentifier = "Concat")]
        public Object Concat()
        {
            String resultConcat = null;
            
            if (FunctionParameters.Length == 0)
                resultConcat = String.Empty;
            else if (FunctionParameters.Length == 2)
            {
                FunctionParameters[0].Accept(Visitor);
                resultConcat = Visitor.Result.ToString();
            }
            else
            {
                foreach (LogicalExpression expr in FunctionParameters)
                {
                    expr.Accept(Visitor);
                    resultConcat += Visitor.Result.ToString();
                }
            }

            return resultConcat;
        }
                
        [FunctionExtension(FunctionIdentifier = "Property")]
        public Object Property()
        {
            if (FunctionParameters.Length != 1)
                throw new BusinessLogicException(
                    ExceptionHelper.excode_property_function_takes_only_1_parameter
                    , "'Property' function takes only 1 parameter");
            FunctionParameters[0].Accept(Visitor);
            String propertyPath = Visitor.Result.ToString();
            return ReflectionHelper.GetValue<Object>(CurrentBusinessEntity, propertyPath);
        }

        [FunctionExtension(FunctionIdentifier = "TimeStamp")]
        public Object GetTimeStamp()
        {
            if (FunctionParameters.Length != 0)
                throw new BusinessLogicException(
                    ExceptionHelper.excode_timestamp_function_has_no_parameters
                    , "'TimeStamp' function has no parameters");
            return TimeStamp;
        }
    }
}
